<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>原子结构可视化（经典模型）</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            color: #fff;
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }
        
        .header {
            text-align: center;
            padding: 20px;
            background: rgba(0, 0, 0, 0.3);
            border-bottom: 1px solid rgba(255, 255, 255, 0.1);
            z-index: 10;
        }
        
        h1 {
            font-size: 2.5rem;
            margin-bottom: 10px;
            background: linear-gradient(to right, #4facfe, #00f2fe);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
        }
        
        .subtitle {
            font-size: 1.1rem;
            opacity: 0.8;
            max-width: 800px;
            margin: 0 auto;
            line-height: 1.6;
        }
        
        .container {
            flex: 1;
            display: flex;
            justify-content: center;
            align-items: center;
            position: relative;
        }
        
        .zoom-info {
            position: absolute;
            top: 20px;
            right: 20px;
            background: rgba(0, 0, 0, 0.5);
            padding: 10px 15px;
            border-radius: 20px;
            font-size: 0.9rem;
            backdrop-filter: blur(5px);
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        canvas {
            background: rgba(0, 0, 0, 0.1);
            border-radius: 8px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
        }
        
        .legend {
            position: absolute;
            bottom: 20px;
            left: 20px;
            background: rgba(0, 0, 0, 0.5);
            padding: 15px;
            border-radius: 10px;
            backdrop-filter: blur(5px);
            border: 1px solid rgba(255, 255, 255, 0.1);
            max-width: 300px;
        }
        
        .legend h3 {
            margin-bottom: 10px;
            color: #00f2fe;
        }
        
        .legend-item {
            display: flex;
            align-items: center;
            margin-bottom: 8px;
        }
        
        .color-box {
            width: 20px;
            height: 20px;
            border-radius: 50%;
            margin-right: 10px;
        }
        
        .instructions {
            position: absolute;
            bottom: 20px;
            right: 20px;
            background: rgba(0, 0, 0, 0.5);
            padding: 15px;
            border-radius: 10px;
            backdrop-filter: blur(5px);
            border: 1px solid rgba(255, 255, 255, 0.1);
            text-align: center;
        }
        
        .footer {
            text-align: center;
            padding: 15px;
            font-size: 0.9rem;
            opacity: 0.7;
            background: rgba(0, 0, 0, 0.3);
        }
        
        @media (max-width: 768px) {
            .header {
                padding: 15px;
            }
            
            h1 {
                font-size: 1.8rem;
            }
            
            .subtitle {
                font-size: 0.9rem;
            }
            
            .legend, .instructions {
                position: relative;
                margin: 10px auto;
                left: 0;
                right: 0;
                width: 90%;
                max-width: none;
            }
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>原子结构可视化（经典模型）</h1>
    </div>
    
    <div class="container">
        <div class="zoom-info"><span id="zoom-level">1x</span></div>
        <canvas id="atomCanvas" width="800" height="600"></canvas>
        
        <div class="legend">
            <h3>粒子图例</h3>
            <div class="legend-item">
                <div class="color-box" style="background: #4CAF50;"></div>
                <div>电子 (Electron)</div>
            </div>
            <div class="legend-item">
                <div class="color-box" style="background: #7E57C2;"></div>
                <div>原子核 (Atomic Nucleus)</div>
            </div>
            <div class="legend-item">
                <div class="color-box" style="background: #FF5252;"></div>
                <div>质子 (Proton)</div>
            </div>
            <div class="legend-item">
                <div class="color-box" style="background: #2196F3;"></div>
                <div>中子 (Neutron)</div>
            </div>
            <div class="legend-item">
                <div class="color-box" style="background: #FFEB3B;"></div>
                <div>上夸克 (Up Quark)</div>
            </div>
            <div class="legend-item">
                <div class="color-box" style="background: #9C27B0;"></div>
                <div>下夸克 (Down Quark)</div>
            </div>
        </div>
        
        <div class="instructions">
            <h3>操作说明</h3>
            <p>使用鼠标滚轮缩放视图</p>
            <p>滚动放大查看更细微结构</p>
            <p>滚动缩小返回上一层级</p>
        </div>
    </div>
    
    <div class="footer">
        原子结构可视化 - 经典太阳系模型| 比例并不精确，仅供演示 | 本页面由AI辅助创建 
    </div>

    <script>
        // 获取Canvas和上下文
        const canvas = document.getElementById('atomCanvas');
        const ctx = canvas.getContext('2d');
        const zoomLevelElement = document.getElementById('zoom-level');
        
        // 调整Canvas大小以适应窗口
        function resizeCanvas() {
            canvas.width = Math.min(window.innerWidth * 0.95, 1000);
            canvas.height = Math.min(window.innerHeight * 0.75, 700);
        }
        
        window.addEventListener('resize', resizeCanvas);
        resizeCanvas();
        
        // 原子参数
        const centerX = canvas.width / 2;
        const centerY = canvas.height / 2;
        
        // 粒子定义
        const particles = {
            electrons: [],
            protons: [],
            neutrons: [],
            quarks: []
        };
        
        // 初始化粒子
        function initParticles() {
            const nucleusRadius = 30;
            const protonCount = 3;
            const neutronCount = 4;
            const nucleonCount = protonCount + neutronCount;
            
            // 电子
            particles.electrons = [];
            var electrons_put = 0;
            
            for(let layer = 1; layer < 3; layer++)
            {
                var max_electrons_in_this_layer = 2*layer*layer;
                
                for(let i = 1; i <= max_electrons_in_this_layer; i++)
                {
                    var remainedElectronsToBePut = protonCount - electrons_put;
                    var a = Math.min(remainedElectronsToBePut, max_electrons_in_this_layer)
                    
                    const radius = 150 + (layer-1) * 40;
                    const speed = 0.01 + (layer-1) * 0.005;
                    const angle = (i/a) * Math.PI * 2;
                    
                    particles.electrons.push({
                        radius: radius,
                        angle: angle,
                        speed: speed,
                        size: 5
                    });
                    
                    electrons_put++;
                    if(electrons_put >= protonCount)
                    {
                        break;
                    }
                }
                if(electrons_put >= protonCount)
                {
                    break;
                }
            }

            // 质子和中子
            particles.protons = [];
            particles.neutrons = [];

            var protons_put = 0;
            var neutrons_put = 0;
            
            for (let i = 0; i < nucleonCount; i++) {
                const angle = (i / nucleonCount) * Math.PI * 2;
                const distance = 0.5 * nucleusRadius;
                const x = Math.cos(angle) * distance;
                const y = Math.sin(angle) * distance;
                
                var choice = 0;
                
                if (protonCount - protons_put > 0 && neutronCount - neutrons_put == 0)
                {
                    choice = 0;
                }
                else if (protonCount - protons_put == 0 && neutronCount - neutrons_put > 0)
                {
                    choice = 1;
                }
                else
                {
                    choice = Math.random() > 0.5 ? 1:0;
                }
                
                if (choice === 0) {
                    // 质子
                    particles.protons.push({
                        x: x,
                        y: y,
                        baseX: x,
                        baseY: y,
                        size: 12,
                        vibration: Math.random() * 0.5 + 0.3
                    });
                    protons_put++;
                } else {
                    // 中子
                    particles.neutrons.push({
                        x: x,
                        y: y,
                        baseX: x,
                        baseY: y,
                        size: 12,
                        vibration: Math.random() * 0.5 + 0.3
                    });
                    neutrons_put++;
                }
            }

            
            // 夸克（在核子内部）
            particles.quarks = [];
            for (let proton of particles.protons) {
                // 每个质子有2个上夸克和1个下夸克
                particles.quarks.push({
                    parent: proton,
                    type: 'up',
                    offsetX: -6,
                    offsetY: -6,
                    baseOffsetX: -6,
                    baseOffsetY: -6,
                    size: 5
                });
                
                particles.quarks.push({
                    parent: proton,
                    type: 'up',
                    offsetX: 6,
                    offsetY: -6,
                    baseOffsetX: 6,
                    baseOffsetY: -6,
                    size: 5
                });
                
                particles.quarks.push({
                    parent: proton,
                    type: 'down',
                    offsetX: 0,
                    offsetY: 6,
                    baseOffsetX: 0,
                    baseOffsetY: 6,
                    size: 5
                });
            }
            
            for (let neutron of particles.neutrons) {
                // 每个中子有1个上夸克和2个下夸克
                particles.quarks.push({
                    parent: neutron,
                    type: 'up',
                    offsetX: 0,
                    offsetY: -6,
                    baseOffsetX: 0,
                    baseOffsetY: -6,
                    size: 5
                });
                
                particles.quarks.push({
                    parent: neutron,
                    type: 'down',
                    offsetX: -6,
                    offsetY: 6,
                    baseOffsetX: -6,
                    baseOffsetY: 6,
                    size: 5
                });
                
                particles.quarks.push({
                    parent: neutron,
                    type: 'down',
                    offsetX: 6,
                    offsetY: 6,
                    baseOffsetX: 6,
                    baseOffsetY: 6,
                    size: 5
                });
            }
        }
        
        // 缩放状态
        const zoomState = {
            level: 1,
            scale: 1,
            targetScale: 1,
            maxScale: 12,
            minScale: 1.0
        };
        
        // 处理滚轮缩放事件
        canvas.addEventListener('wheel', function(e) {
            e.preventDefault();
            
            const delta = e.deltaY > 0 ? 0.9 : 1.1;
            zoomState.targetScale *= delta;
            
            // 限制缩放范围
            zoomState.targetScale = Math.max(zoomState.minScale, Math.min(zoomState.targetScale, zoomState.maxScale));
            
            // 更新缩放级别文本
            updateZoomLevelText();
        });
        
        // 更新缩放级别文本
        function updateZoomLevelText() {
            let levelText;
            
            if (zoomState.scale < 5) {
                levelText = "原子";
            } else if (zoomState.scale < 10) {
                levelText = "原子核 (质子/中子)";
            } else {
                levelText = "夸克";
            }
            //levelText = `${zoomState.scale}`
            zoomLevelElement.textContent = `${levelText}`;
        }
        
        // 更新粒子动画
        function updateParticles() {
            // 更新电子位置
            for (let electron of particles.electrons) {
                electron.angle += electron.speed;
                if (electron.angle > Math.PI * 2) {
                    electron.angle -= Math.PI * 2;
                }
            }
            
            // 更新核子振动
            const time = Date.now() * 0.001;
            
            for (let proton of particles.protons) {
                proton.x = proton.baseX + Math.sin(time * proton.vibration) * 2;
                proton.y = proton.baseY + Math.cos(time * proton.vibration * 1.2) * 2;
            }
            
            for (let neutron of particles.neutrons) {
                neutron.x = neutron.baseX + Math.sin(time * neutron.vibration * 0.8) * 2;
                neutron.y = neutron.baseY + Math.cos(time * neutron.vibration * 1.5) * 2;
            }
            
            // 更新夸克运动
            for (let quark of particles.quarks) {
                const wave = Math.sin(time * 2) * 0.5;
                quark.offsetX = quark.baseOffsetX + Math.sin(time * 1.5 + quark.baseOffsetX) * 2;
                quark.offsetY = quark.baseOffsetY + Math.cos(time * 1.2 + quark.baseOffsetY) * 2;
            }
        }
        
        // 绘制原子结构
        function draw() {
            // 平滑缩放
            zoomState.scale += (zoomState.targetScale - zoomState.scale) * 0.1;
            
            // 更新缩放级别显示
            updateZoomLevelText();
            
            // 清除画布
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // 更新粒子位置
            updateParticles();
            
            // 保存当前状态
            ctx.save();
            
            // 应用缩放和平移
            ctx.translate(centerX, centerY);
            ctx.scale(zoomState.scale, zoomState.scale);
            ctx.translate(-centerX, -centerY);
            
            
            // 绘制电子
            if (1) {
                for (let electron of particles.electrons) {
                    const x = centerX + Math.cos(electron.angle) * electron.radius;
                    const y = centerY + Math.sin(electron.angle) * electron.radius;
                    
                    // 电子光晕效果
                    const gradient = ctx.createRadialGradient(x, y, 0, x, y, electron.size * 2);
                    gradient.addColorStop(0, 'rgba(76, 175, 80, 0.8)');
                    gradient.addColorStop(1, 'rgba(76, 175, 80, 0)');
                    
                    ctx.beginPath();
                    ctx.arc(x, y, electron.size * 2, 0, Math.PI * 2);
                    ctx.fillStyle = gradient;
                    ctx.fill();
                    
                    // 电子主体
                    ctx.beginPath();
                    ctx.arc(x, y, electron.size, 0, Math.PI * 2);
                    ctx.fillStyle = '#4CAF50';
                    ctx.fill();
                    
                    //电子轨道
                    ctx.beginPath();
                    ctx.arc(centerX, centerY, electron.radius, 0, Math.PI * 2);
                    ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
                    ctx.setLineDash([5, 5]);
                    ctx.lineWidth = 1;
                    ctx.stroke();
                    ctx.setLineDash([]);
                }
            }
            
            // 绘制原子核草图
            if (zoomState.scale < 6) {
                // 原子核背景光晕
                const nucleusGradient = ctx.createRadialGradient(
                    centerX, centerY, 0, 
                    centerX, centerY, 60
                );
                nucleusGradient.addColorStop(0, 'rgba(100, 100, 100, 0.6)');
                nucleusGradient.addColorStop(1, 'rgba(100, 100, 100, 0)');
                
                ctx.beginPath();
                ctx.arc(centerX, centerY, 60, 0, Math.PI * 2);
                ctx.fillStyle = nucleusGradient;
                ctx.fill();
                
                //原子核主体
                var alpha = -(zoomState.scale-6);
                if (alpha < 0) alpha = 0;
                if (alpha > 1) alpha = 1;
                
                ctx.beginPath();
                ctx.arc(centerX, centerY, 20, 0, Math.PI * 2);
                ctx.fillStyle = `rgba(126,87,194,${alpha})`;
                ctx.fill();
                
                ctx.font = '10px Arial';
                ctx.fillStyle = 'white';
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.fillText('原子核', centerX, centerY);
            }
            
            // 绘制质子和中子（在中等缩放级别显示）
            if (zoomState.scale > 5 && zoomState.scale < 11) {
            
                var alpha1 = (zoomState.scale-5);
                var alpha2 = -(zoomState.scale-11);
                var alpha = Math.min(alpha1,alpha2);
                if (alpha < 0) alpha = 0;
                if (alpha > 1) alpha = 1;
                
                for (let proton of particles.protons) {
                    const x = centerX + proton.x;
                    const y = centerY + proton.y;
                    
                    // 光晕
                    const gradient = ctx.createRadialGradient(x, y, 0, x, y, proton.size * 1.5);
                    gradient.addColorStop(0, 'rgba(255, 82, 82, 0.6)');
                    gradient.addColorStop(1, 'rgba(255, 82, 82, 0)');
                    
                    ctx.beginPath();
                    ctx.arc(x, y, proton.size * 1.5, 0, Math.PI * 2);
                    ctx.fillStyle = gradient;
                    ctx.fill();
                    
                    // 主体
                    ctx.beginPath();
                    ctx.arc(x, y, proton.size, 0, Math.PI * 2);
                    ctx.fillStyle = `rgba(255,82,82,${alpha})`;
                    ctx.fill();
                    
                    ctx.font = '10px Arial';
                    ctx.fillStyle = 'white';
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'middle';
                    ctx.fillText('p', x, y);
                    
                }

                for (let neutron of particles.neutrons) {
                    const x = centerX + neutron.x;
                    const y = centerY + neutron.y;
                    
                    // 光晕
                    const gradient = ctx.createRadialGradient(x, y, 0, x, y, neutron.size * 1.5);
                    gradient.addColorStop(0, 'rgba(33, 150, 243, 0.6)');
                    gradient.addColorStop(1, 'rgba(33, 150, 243, 0)');
                    
                    ctx.beginPath();
                    ctx.arc(x, y, neutron.size * 1.5, 0, Math.PI * 2);
                    ctx.fillStyle = gradient;
                    ctx.fill();
                    
                    // 主体
                    ctx.beginPath();
                    ctx.arc(x, y, neutron.size, 0, Math.PI * 2);
                    ctx.fillStyle = `rgba(33,150,243,${alpha})`;
                    ctx.fill();
                    
                    // 绘制中子标签
                    ctx.font = '10px Arial';
                    ctx.fillStyle = 'white';
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'middle';
                    ctx.fillText('n', x, y);

                }
            }
            
            // 绘制夸克（在高缩放级别显示）
            if (zoomState.scale > 10) {
            
                var alpha = (zoomState.scale - 10);
                if (alpha < 0) alpha = 0;
                if (alpha > 1) alpha = 1;
                
                for (let quark of particles.quarks) {
                    const parent = quark.parent;
                    const x = centerX + parent.x + quark.offsetX;
                    const y = centerY + parent.y + quark.offsetY;
                    
                    // 夸克颜色
                    const color = quark.type === 'up' ? '#FFEB3B' : '#9C27B0';
                    const color2 = quark.type === 'up' ? `rgba(255,235,59,${alpha})` : `rgba(156,39,176,${alpha})`
                    
                    // 光晕
                    const gradient = ctx.createRadialGradient(x, y, 0, x, y, quark.size * 2);
                    gradient.addColorStop(0, `${color}80`);
                    gradient.addColorStop(1, `${color}00`);
                    
                    ctx.beginPath();
                    ctx.arc(x, y, quark.size * 2, 0, Math.PI * 2);
                    ctx.fillStyle = gradient;
                    ctx.fill();
                    
                    // 主体
                    ctx.beginPath();
                    ctx.arc(x, y, quark.size, 0, Math.PI * 2);
                    ctx.fillStyle = color2;
                    ctx.fill();
                    
                    // 绘制夸克标签
                    ctx.font = '8px Arial';
                    ctx.fillStyle = 'white';
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'middle';
                    ctx.fillText(quark.type === 'up' ? 'u' : 'd', x, y);
                }
                
                // 绘制核子轮廓（在高缩放级别显示）
                for (let proton of particles.protons) {
                    const x = centerX + proton.x;
                    const y = centerY + proton.y;
                    
                    ctx.beginPath();
                    ctx.arc(x, y, proton.size, 0, Math.PI * 2);
                    ctx.strokeStyle = 'rgba(255, 82, 82, 0.3)';
                    ctx.lineWidth = 1;
                    ctx.stroke();
                }
                
                for (let neutron of particles.neutrons) {
                    const x = centerX + neutron.x;
                    const y = centerY + neutron.y;
                    
                    ctx.beginPath();
                    ctx.arc(x, y, neutron.size, 0, Math.PI * 2);
                    ctx.strokeStyle = 'rgba(33, 150, 243, 0.3)';
                    ctx.lineWidth = 1;
                    ctx.stroke();
                }
            }
            
            // 恢复状态
            ctx.restore();
            
            // 下一帧
            requestAnimationFrame(draw);
        }
        
        // 初始化并开始动画
        initParticles();
        updateZoomLevelText();
        draw();
    </script>
</body>
</html>